﻿namespace Numbrella.ProblemProvider
{
	using System;
	using System.ComponentModel;
	using System.Drawing;
	using System.IO;
	using System.Text;
	using System.Windows;
	using Microsoft.Win32;
	using Numbrella.Client.Common;

	internal partial class MainWindow
	{
		private System.Windows.Forms.NotifyIcon trayIcon;

		private ProblemProvidingEngine problemProvider;
		
		public MainWindow()
		{
			this.InitializeComponent();
			this.AddToTray();
			this.ConnectToProblemProvider();
		}

		protected override void OnStateChanged(EventArgs e)
		{
			if (this.WindowState == WindowState.Minimized)
				this.Hide();

			base.OnStateChanged(e);
		}

		private void ConnectToProblemProvider()
		{
			this.problemProvider = ((App) Application.Current).ProblemProvider;
			this.problemProvider.SolveProblemCompleted += this.OnProblemProviderSolveProblemCompleted; 
		}

		private void AddToTray()
		{
			System.Windows.Forms.ContextMenu menu = new System.Windows.Forms.ContextMenu();
			menu.MenuItems.Add("Expand", (sender, e) => this.ExpandWindow());
			menu.MenuItems.Add("Exit", (sender, e) => this.Close());

			this.trayIcon = new System.Windows.Forms.NotifyIcon
								{
									Icon = new Icon("Default.ico"),
									ContextMenu = menu,
									Visible = true,
								};

			this.trayIcon.DoubleClick += (sender, e) => this.ExpandWindow();
		}

		private void ExpandWindow()
		{
			this.Show();
			this.WindowState = WindowState.Normal;
		}

		#region Event handlers

		private void OnWindowLoaded(object sender, RoutedEventArgs e)
		{
			this.logListBox.ItemsSource = Logger.Instance.LogRecords;
		}

		private void OnWindowClosing(object sender, CancelEventArgs e)
		{
			if (this.problemProvider.CurrentProblem != null)
			{
				e.Cancel = true;
				MessageBox.Show(
					"You should cancel providing your problem first!",
					"Warning",
					MessageBoxButton.OK,
					MessageBoxImage.Warning);
			}
		}

		private void OnWindowClosed(object sender, EventArgs e)
		{
			this.trayIcon.Visible = false;
		}

		private void OnSaveLogButtonClick(object sender, RoutedEventArgs e)
		{
			SaveFileDialog dialog = new SaveFileDialog { RestoreDirectory = true };
			if (dialog.ShowDialog() == true)
			{
				string[] logStrings = new string[Logger.Instance.LogRecords.Count];
				Logger.Instance.LogRecords.CopyTo(logStrings, 0);
				File.WriteAllLines(dialog.FileName, logStrings, Encoding.UTF8);
			}
		}

		private void OnClearLogButtonClick(object sender, RoutedEventArgs e)
		{
			Logger.Instance.Clear();
		}

		private void OnOptionsButtonClick(object sender, RoutedEventArgs e)
		{
			OptionsWindow optionsWindow = new OptionsWindow();
			optionsWindow.ShowDialog();
		}

		private void OnSolveOwnTaskButtonClick(object sender, RoutedEventArgs e)
		{
			OpenFileDialog dialog = new OpenFileDialog { RestoreDirectory = true };
			if (dialog.ShowDialog() != true)
				return;

			try
			{
				this.problemProvider.SolveProblemAsync(dialog.FileName);
			}
			catch (Exception exception)
			{
				MessageBox.Show(exception.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
				return;
			}

			this.solveProblemButton.IsEnabled = false;
			this.optionsButton.IsEnabled = false;
			this.stopSolvingButton.IsEnabled = true;
		}

		private void OnStopSolvingOwnTaskButtonClick(object sender, RoutedEventArgs e)
		{
			this.stopSolvingButton.IsEnabled = false;
			this.problemProvider.CancelAsync();
		}

		private void OnProblemProviderSolveProblemCompleted(object sender, AsyncCompletedEventArgs e)
		{
			this.solveProblemButton.IsEnabled = true;
			this.optionsButton.IsEnabled = true;
			this.stopSolvingButton.IsEnabled = false;
		}

		#endregion
	}
}